package com.nbcio.modules.erp.price.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nbcio.common.core.domain.R;
import com.nbcio.modules.erp.price.domain.ErpPrice;
import com.nbcio.modules.erp.price.mapper.ErpPriceMapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@Tag(name = "价目表维护")
@RestController
@RequestMapping("/erp/price")
@RequiredArgsConstructor
public class ErpPriceCrudController {

    private final ErpPriceMapper priceMapper;

    @GetMapping("/page")
    public R<IPage<ErpPrice>> page(@RequestParam int pageNum,
                                   @RequestParam int pageSize,
                                   @RequestParam(required = false) String billType,
                                   @RequestParam(required = false) String materialId,
                                   @RequestParam(required = false) String partyId) {
        LambdaQueryWrapper<ErpPrice> qw = new LambdaQueryWrapper<>();
        if (billType != null && !billType.isEmpty()) qw.eq(ErpPrice::getBillType, billType);
        if (materialId != null && !materialId.isEmpty()) qw.eq(ErpPrice::getMaterialId, Long.parseLong(materialId));
        if (partyId != null && !partyId.isEmpty()) qw.eq(ErpPrice::getPartyId, Long.parseLong(partyId));
        qw.orderByDesc(ErpPrice::getStartTime);
        return R.ok(priceMapper.selectPage(Page.of(pageNum, pageSize), qw));
    }

    @GetMapping("/{id}")
    public R<ErpPrice> get(@PathVariable("id") String id) {
        return R.ok(priceMapper.selectById(Long.parseLong(id)));
    }

    @PostMapping
    public R<Boolean> create(@RequestBody ErpPrice price) {
        if (hasOverlap(price, null)) {
            return R.fail("生效区间与已存在的价格冲突");
        }
        return R.ok(priceMapper.insert(price) > 0);
    }

    @PutMapping("/{id}")
    public R<Boolean> update(@PathVariable("id") String id, @RequestBody ErpPrice price) {
        price.setPriceId(Long.parseLong(id));
        if (hasOverlap(price, price.getPriceId())) {
            return R.fail("生效区间与已存在的价格冲突");
        }
        return R.ok(priceMapper.updateById(price) > 0);
    }

    @DeleteMapping("/{id}")
    public R<Boolean> delete(@PathVariable("id") String id) {
        return R.ok(priceMapper.deleteById(Long.parseLong(id)) > 0);
    }

    /**
     * 检查价格生效区间是否冲突
     */
    private boolean hasOverlap(ErpPrice p, Long excludeId) {
        LambdaQueryWrapper<ErpPrice> qw = new LambdaQueryWrapper<>();
        qw.eq(ErpPrice::getBillType, p.getBillType())
          .eq(ErpPrice::getMaterialId, p.getMaterialId());
        if (p.getPartyId() == null) {
            qw.isNull(ErpPrice::getPartyId);
        } else {
            qw.eq(ErpPrice::getPartyId, p.getPartyId());
        }
        if (p.getUomId() == null) {
            qw.isNull(ErpPrice::getUomId);
        } else {
            qw.eq(ErpPrice::getUomId, p.getUomId());
        }
        if (excludeId != null) {
            qw.ne(ErpPrice::getPriceId, excludeId);
        }
        java.time.LocalDateTime st = p.getStartTime();
        java.time.LocalDateTime et = p.getEndTime();
        // overlap: a.start <= b.end && (a.end is null or a.end >= b.start)
        qw.and(w -> w.le(ErpPrice::getStartTime, et == null ? java.time.LocalDateTime.of(2999,12,31,23,59,59) : et)
                     .and(w2 -> w2.ge(ErpPrice::getEndTime, st).or().isNull(ErpPrice::getEndTime)));
        return priceMapper.selectCount(qw) > 0;
    }
}


